// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.core.Collections;

import java.io.Serializable;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import sun.misc.Unsafe;

public class ConcurrentAutoTable implements Serializable {
    private volatile ConcurrentAutoTable.CAT _cat = new ConcurrentAutoTable.CAT(null, 4, 0L);
    private static final AtomicReferenceFieldUpdater<ConcurrentAutoTable, ConcurrentAutoTable.CAT> _catUpdater = AtomicReferenceFieldUpdater.newUpdater(
        ConcurrentAutoTable.class, ConcurrentAutoTable.CAT.class, "_cat"
    );

    public void add(long x) {
        this.add_if_mask(x, 0L);
    }

    public void decrement() {
        this.add_if_mask(-1L, 0L);
    }

    public void increment() {
        this.add_if_mask(1L, 0L);
    }

    public void set(long x) {
        ConcurrentAutoTable.CAT cAT = new ConcurrentAutoTable.CAT(null, 4, x);

        while (!this.CAS_cat(this._cat, cAT)) {
        }
    }

    public long get() {
        return this._cat.sum(0L);
    }

    public int intValue() {
        return (int)this._cat.sum(0L);
    }

    public long longValue() {
        return this._cat.sum(0L);
    }

    public long estimate_get() {
        return this._cat.estimate_sum(0L);
    }

    public String toString() {
        return this._cat.toString(0L);
    }

    public void print() {
        this._cat.print();
    }

    public int internal_size() {
        return this._cat._t.length;
    }

    private long add_if_mask(long long0, long long1) {
        return this._cat.add_if_mask(long0, long1, hash(), this);
    }

    private boolean CAS_cat(ConcurrentAutoTable.CAT cAT0, ConcurrentAutoTable.CAT cAT1) {
        return _catUpdater.compareAndSet(this, cAT0, cAT1);
    }

    private static final int hash() {
        int _int = System.identityHashCode(Thread.currentThread());
        _int ^= _int >>> 20 ^ _int >>> 12;
        _int ^= _int >>> 7 ^ _int >>> 4;
        return _int << 2;
    }

    private static class CAT implements Serializable {
        private static final Unsafe _unsafe = UtilUnsafe.getUnsafe();
        private static final int _Lbase = _unsafe.arrayBaseOffset(long[].class);
        private static final int _Lscale = _unsafe.arrayIndexScale(long[].class);
        volatile long _resizers;
        private static final AtomicLongFieldUpdater<ConcurrentAutoTable.CAT> _resizerUpdater = AtomicLongFieldUpdater.newUpdater(
            ConcurrentAutoTable.CAT.class, "_resizers"
        );
        private final ConcurrentAutoTable.CAT _next;
        private volatile long _sum_cache;
        private volatile long _fuzzy_sum_cache;
        private volatile long _fuzzy_time;
        private static final int MAX_SPIN = 2;
        private long[] _t;

        private static long rawIndex(long[] _long, int _int) {
            assert _int >= 0 && _int < _long.length;

            return (long)(_Lbase + _int * _Lscale);
        }

        private static final boolean CAS(long[] long0, int _int, long long1, long long2) {
            return _unsafe.compareAndSwapLong(long0, rawIndex(long0, _int), long1, long2);
        }

        CAT(ConcurrentAutoTable.CAT cAT1, int _int, long _long) {
            this._next = cAT1;
            this._sum_cache = Long.MIN_VALUE;
            this._t = new long[_int];
            this._t[0] = _long;
        }

        public long add_if_mask(long long2, long long3, int int1, ConcurrentAutoTable concurrentAutoTable) {
            long[] long0 = this._t;
            int int0 = int1 & long0.length - 1;
            long long1 = long0[int0];
            boolean _boolean = CAS(long0, int0, long1 & ~long3, long1 + long2);
            if (this._sum_cache != Long.MIN_VALUE) {
                this._sum_cache = Long.MIN_VALUE;
            }

            if (_boolean) {
                return long1;
            } else if ((long1 & long3) != 0L) {
                return long1;
            } else {
                int int2 = 0;

                while (true) {
                    long1 = long0[int0];
                    if ((long1 & long3) != 0L) {
                        return long1;
                    }

                    if (CAS(long0, int0, long1, long1 + long2)) {
                        if (int2 < 2) {
                            return long1;
                        }

                        if (long0.length >= 1048576) {
                            return long1;
                        }

                        long long4 = this._resizers;
                        int int3 = long0.length << 1 << 3;

                        while (!_resizerUpdater.compareAndSet(this, long4, long4 + (long)int3)) {
                            long4 = this._resizers;
                        }

                        long4 += (long)int3;
                        if (concurrentAutoTable._cat != this) {
                            return long1;
                        }

                        if (long4 >> 17 != 0L) {
                            try {
                                Thread.sleep(long4 >> 17);
                            } catch (InterruptedException interruptedException) {
                            }

                            if (concurrentAutoTable._cat != this) {
                                return long1;
                            }
                        }

                        ConcurrentAutoTable.CAT cAT1 = new ConcurrentAutoTable.CAT(this, long0.length * 2, 0L);
                        concurrentAutoTable.CAS_cat(this, cAT1);
                        return long1;
                    }

                    int2++;
                }
            }
        }

        public long sum(long long1) {
            long long0 = this._sum_cache;
            if (long0 != Long.MIN_VALUE) {
                return long0;
            } else {
                long0 = this._next == null ? 0L : this._next.sum(long1);
                long[] long2 = this._t;

                for (int _int = 0; _int < long2.length; _int++) {
                    long0 += long2[_int] & ~long1;
                }

                this._sum_cache = long0;
                return long0;
            }
        }

        public long estimate_sum(long long0) {
            if (this._t.length <= 64) {
                return this.sum(long0);
            } else {
                long long1 = System.currentTimeMillis();
                if (this._fuzzy_time != long1) {
                    this._fuzzy_sum_cache = this.sum(long0);
                    this._fuzzy_time = long1;
                }

                return this._fuzzy_sum_cache;
            }
        }

        public void all_or(long long2) {
            long[] long0 = this._t;

            for (int _int = 0; _int < long0.length; _int++) {
                boolean _boolean = false;

                while (!_boolean) {
                    long long1 = long0[_int];
                    _boolean = CAS(long0, _int, long1, long1 | long2);
                }
            }

            if (this._next != null) {
                this._next.all_or(long2);
            }

            if (this._sum_cache != Long.MIN_VALUE) {
                this._sum_cache = Long.MIN_VALUE;
            }
        }

        public void all_and(long long2) {
            long[] long0 = this._t;

            for (int _int = 0; _int < long0.length; _int++) {
                boolean _boolean = false;

                while (!_boolean) {
                    long long1 = long0[_int];
                    _boolean = CAS(long0, _int, long1, long1 & long2);
                }
            }

            if (this._next != null) {
                this._next.all_and(long2);
            }

            if (this._sum_cache != Long.MIN_VALUE) {
                this._sum_cache = Long.MIN_VALUE;
            }
        }

        public void all_set(long long1) {
            long[] long0 = this._t;

            for (int _int = 0; _int < long0.length; _int++) {
                long0[_int] = long1;
            }

            if (this._next != null) {
                this._next.all_set(long1);
            }

            if (this._sum_cache != Long.MIN_VALUE) {
                this._sum_cache = Long.MIN_VALUE;
            }
        }

        String toString(long _long) {
            return Long.toString(this.sum(_long));
        }

        public void print() {
            long[] _long = this._t;
            System.out.print("[sum=" + this._sum_cache + "," + _long[0]);

            for (int _int = 1; _int < _long.length; _int++) {
                System.out.print("," + _long[_int]);
            }

            System.out.print("]");
            if (this._next != null) {
                this._next.print();
            }
        }
    }
}
